from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from selenium.webdriver.chrome.service import Service
import pandas as pd
import time
import random
import os

# 配置参数
output_file = 'video_likes.txt'  # 结果文件
page_load_timeout = 30  # 页面加载超时时间（秒）
element_wait_timeout = 20  # 元素等待超时时间（秒）


def extract_likes(driver, sec_uid, username):
    """用Selenium提取用户视频的链接和点赞量"""
    results = []
    user_url = f'https://www.douyin.com/user/{sec_uid}'

    try:
        # 设置页面加载超时时间
        driver.set_page_load_timeout(page_load_timeout)
        driver.get(user_url)
        print(f"\n已打开用户主页：{user_url}")

        # 处理可能的登录弹窗（如果出现）
        try:
            close_btn = WebDriverWait(driver, 5).until(
                EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), '关闭')]"))
            )
            close_btn.click()
            print("已关闭登录弹窗")
        except:
            pass

        # 等待视频元素加载（尝试多种可能的定位方式）
        try:
            # 尝试等待最新的视频容器元素
            WebDriverWait(driver, element_wait_timeout).until(
                EC.presence_of_element_located(
                    (By.XPATH, "//div[contains(@class, 'Eie048Y6') or contains(@class, 'video-container')]"))
            )
        except TimeoutException:
            # 如果默认方式失败，尝试另一种定位方式
            print("尝试备用定位方式...")
            WebDriverWait(driver, element_wait_timeout).until(
                EC.presence_of_element_located((By.XPATH, "//a[contains(@href, '/video/')]"))
            )

        # 滚动加载更多视频
        last_height = driver.execute_script("return document.body.scrollHeight")
        scroll_count = 0
        max_scroll = 10  # 最多滚动10次

        while scroll_count < max_scroll:
            # 提取当前页面所有视频的链接和点赞量
            video_items = driver.find_elements(By.XPATH, "//a[contains(@href, '/video/')]")

            for item in video_items:
                try:
                    video_link = item.get_attribute('href')
                    if not video_link or 'video' not in video_link:
                        continue

                    # 尝试多种可能的点赞元素定位方式
                    try:
                        # 方式1：使用你找到的class
                        like_element = item.find_element(By.XPATH, ".//span[@class='BgCg_ebQ']")
                    except NoSuchElementException:
                        # 方式2：使用可能的其他class（根据实际情况调整）
                        like_element = item.find_element(By.XPATH,
                                                         ".//span[contains(@class, 'like-count') or contains(@class, 'digg-count')]")

                    like_text = like_element.text.strip()

                    # 处理点赞量格式
                    if 'w' in like_text:
                        like_count = int(float(like_text.replace('w', '')) * 10000)
                    elif 'k' in like_text:
                        like_count = int(float(like_text.replace('k', '')) * 1000)
                    else:
                        like_count = int(like_text) if like_text.isdigit() else 0

                    if (video_link, like_count) not in results:
                        results.append((video_link, like_count))
                        print(f"✅ 提取：{video_link}  点赞量：{like_count}")

                except Exception as e:
                    continue

            # 滚动到页面底部
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            time.sleep(random.uniform(2, 4))
            new_height = driver.execute_script("return document.body.scrollHeight")

            if new_height == last_height:
                print("已加载完所有视频")
                break

            last_height = new_height
            scroll_count += 1

    except TimeoutException:
        print(f"❌ 用户 {username} 主页加载超时")
    except Exception as e:
        print(f"❌ 处理用户 {username} 时出错：{str(e)}")

    return results


if __name__ == '__main__':
    # 读取用户数据
    sec_uids = [line.strip() for line in open('SecUid.txt', 'r', encoding='utf-8') if line.strip()]
    df = pd.read_excel('data.xlsx', header=0)
    usernames = df.iloc[:, 1].tolist()

    # 配置Selenium浏览器
    options = webdriver.ChromeOptions()
    options.add_argument("--start-maximized")
    options.add_argument("--disable-blink-features=AutomationControlled")
    options.add_argument("--disable-extensions")
    options.add_argument("--disable-notifications")
    options.add_argument("--disable-infobars")
    options.add_argument("--disable-gpu")
    options.add_argument("--no-sandbox")

    # 使用随机User-Agent
    user_agents = [
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
    ]
    options.add_argument(f"user-agent={random.choice(user_agents)}")

    # 创建浏览器实例
    driver = webdriver.Chrome(options=options)

    # 处理每个用户
    with open(output_file, 'w', encoding='utf-8') as f:
        for i in range(len(sec_uids)):
            sec_uid = sec_uids[i]
            username = usernames[i] if i < len(usernames) else ""
            print(f"\n===== 开始处理用户：{username} =====")

            # 提取视频链接和点赞量
            video_data = extract_likes(driver, sec_uid, username)

            # 写入文件
            for link, like in video_data:
                f.write(f"{link}\t{like}\n")

            # 随机等待，降低反爬风险
            time.sleep(random.uniform(5, 10))

    driver.quit()
    print(f"\n🎉 所有处理完成，结果已保存到 {output_file}")